printing: Fix memory leak when listing Avahi printers
authorMarek Kasik <mkasik@redhat.com>
Fri, 22 Nov 2013 10:31:25 +0000 (11:31 +0100)
committerMarek Kasik <mkasik@redhat.com>
Mon, 25 Nov 2013 09:27:39 +0000 (10:27 +0100)
Return values of g_variant_get_child_value() were not unreffed
correctly together with one value returned by g_variant_get().
Use g_variant_get_data() instead of copying each byte separately.

https://bugzilla.gnome.org/show_bug.cgi?id=712799

modules/printbackends/cups/gtkprintbackendcups.c

index 53c7de162d70f0116dabd735f1584168a0cb151f..0573f45cc9e78de617b9262cce8f94d9d0caab66 100644 (file)
@@ -2697,10 +2697,11 @@ avahi_service_resolver_cb (GObject      *source_object,
   gchar                   *endptr;
   gchar                   *key;
   gchar                   *value;
+  gsize                    length;
   gint                     interface;
   gint                     protocol;
   gint                     aprotocol;
-  gint                     i, j;
+  gint                     i;
 
   output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
                                           res,
@@ -2728,50 +2729,55 @@ avahi_service_resolver_cb (GObject      *source_object,
         {
           child = g_variant_get_child_value (txt, i);
 
-          tmp = g_new0 (gchar, g_variant_n_children (child) + 1);
-          for (j = 0; j < g_variant_n_children (child); j++)
+          length = g_variant_get_size (child);
+          if (length > 0)
             {
-              tmp[j] = g_variant_get_byte (g_variant_get_child_value (child, j));
-            }
+              tmp = g_strndup (g_variant_get_data (child), length);
+              g_variant_unref (child);
 
-          if (!avahi_txt_get_key_value_pair (tmp, &key, &value))
-            {
-              g_free (tmp);
-              continue;
-            }
+              if (!avahi_txt_get_key_value_pair (tmp, &key, &value))
+                {
+                  g_free (tmp);
+                  continue;
+                }
 
-          if (g_strcmp0 (key, "rp") == 0)
-            {
-              queue_name = g_strdup (value);
+              if (g_strcmp0 (key, "rp") == 0)
+                {
+                  queue_name = g_strdup (value);
 
-              printer_name = g_strrstr (queue_name, "/");
-              if (printer_name != NULL)
-                data->printer_name = g_strdup (printer_name + 1);
-              else
-                data->printer_name = g_strdup (queue_name);
-            }
-          else if (g_strcmp0 (key, "note") == 0)
-            {
-              data->location = g_strdup (value);
-            }
-          else if (g_strcmp0 (key, "printer-type") == 0)
-            {
-              endptr = NULL;
-              data->printer_type = g_ascii_strtoull (value, &endptr, 16);
-              if (data->printer_type != 0 || endptr != value)
-                data->got_printer_type = TRUE;
+                  printer_name = g_strrstr (queue_name, "/");
+                  if (printer_name != NULL)
+                    data->printer_name = g_strdup (printer_name + 1);
+                  else
+                    data->printer_name = g_strdup (queue_name);
+                }
+              else if (g_strcmp0 (key, "note") == 0)
+                {
+                  data->location = g_strdup (value);
+                }
+              else if (g_strcmp0 (key, "printer-type") == 0)
+                {
+                  endptr = NULL;
+                  data->printer_type = g_ascii_strtoull (value, &endptr, 16);
+                  if (data->printer_type != 0 || endptr != value)
+                    data->got_printer_type = TRUE;
+                }
+              else if (g_strcmp0 (key, "printer-state") == 0)
+                {
+                  endptr = NULL;
+                  data->printer_state = g_ascii_strtoull (value, &endptr, 10);
+                  if (data->printer_state != 0 || endptr != value)
+                    data->got_printer_state = TRUE;
+                }
+
+              g_clear_pointer (&key, g_free);
+              g_clear_pointer (&value, g_free);
+              g_free (tmp);
             }
-          else if (g_strcmp0 (key, "printer-state") == 0)
+          else
             {
-              endptr = NULL;
-              data->printer_state = g_ascii_strtoull (value, &endptr, 10);
-              if (data->printer_state != 0 || endptr != value)
-                data->got_printer_state = TRUE;
+              g_variant_unref (child);
             }
-
-          g_clear_pointer (&key, g_free);
-          g_clear_pointer (&value, g_free);
-          g_free (tmp);
         }
 
       if (queue_name)
@@ -2810,6 +2816,7 @@ avahi_service_resolver_cb (GObject      *source_object,
           g_free (data);
         }
 
+      g_variant_unref (txt);
       g_variant_unref (output);
     }
   else